import sqlite3
import os
import time
import hashlib
from http.cookies import SimpleCookie
from . import userlib

class LoginError(Exception):
  def __init__(self, reason):
    self.reason = reason
  def __str__(self):
    return repr(self.reason)

class LogoutError(Exception):
  def __init__(self, reason):
    self.reason = reason
  def __str__(self):
    return repr(self.reason)

"""
Returns the sid cookie for the current browser session
"""
def get_sid():
  try:
    cookies = SimpleCookie(os.environ["HTTP_COOKIE"])
    sid = cookies["pygallery_sid"].value
    return sid
  except KeyError:
    return -1

"""
Returns a generated sid
"""
def make_sid(username, password):
  hash_str = username + password + str(time.time())
  sid = hashlib.sha224(hash_str.encode("ascii")).hexdigest()
  return sid

"""
Raises LoginError if login fails
Returns sid if login successful
"""
def login(username, password):
  user = userlib.get_user(username, password)
  # If no rows were returned user does not exist
  if (user == None):
    raise LoginError("User not found")
  else:
    # Insert user session
    conn = sqlite3.connect(os.environ["DOCUMENT_ROOT"] 
        + "/PictureShare/pygallery.sqlite")
    session_cur = conn.cursor()
    sid = make_sid(username, password)
    session_cur.execute("""
      insert into user_sessions (user_session_id, user_id, login_time)
      values (?, ?, ?)
      """, (sid, user["user_id"], time.time()))
    conn.commit()
    session_cur.close()
    conn.close()
    return sid 

"""
Deletes user session
Raises LogoutError if logout unsuccessful
"""
def logout(sid=-1):
  if sid == -1:
    sid = get_sid()
    if sid == -1:
      # No session
      raise LogoutError("User is not logged in.")
  # Delete user session
  conn = sqlite3.connect(os.environ["DOCUMENT_ROOT"] 
      + "/PictureShare/pygallery.sqlite")
  session_cur = conn.cursor()
  session_cur.execute("""
    delete from user_sessions
    where user_session_id = ?
    """, (sid,))
  conn.commit()
  session_cur.close()
  conn.close()
  if logged_in(sid):
    raise LogoutError("Database error")

def get_session_user():
  sid = get_sid()
  conn = sqlite3.connect(os.environ["DOCUMENT_ROOT"] 
      + "/PictureShare/pygallery.sqlite")
  conn.row_factory = sqlite3.Row
  session_cur = conn.cursor()
  session_cur.execute("""
    select us.user_id from user_sessions us
    where us.user_session_id = ?
    """, (sid,))
  session = session_cur.fetchone()
  user = userlib.get_user_by_id(session["user_id"])
  session_cur.close()
  conn.close()
  return user

def logged_in(sid=-1):
  conn = sqlite3.connect(os.environ["DOCUMENT_ROOT"] 
      + "/PictureShare/pygallery.sqlite")
  conn.row_factory = sqlite3.Row
  session_cur = conn.cursor()
  if sid == -1:
    sid = get_sid()
  session_cur.execute("""
    select us.user_id from user_sessions us
    where us.user_session_id = ?
    """, (sid,))
  session = session_cur.fetchone()
  session_cur.close()
  conn.close()
  return (session != None)
